package avicit.bdp.dgs.qa.service.algo.raw.data.pcm.utils;

import avicit.bdp.dgs.qa.service.algo.raw.data.pcm.entity.PcmTime;

import java.math.BigDecimal;
import java.util.Date;

/**
 * @金航数码科技有限责任公司
 * @作者：developer
 * @邮箱：developer@avic-digital.com
 * @创建时间： 2023-11-01
 * @类说明：DataConvertUtils
 * @修改记录：
 * @注意事项：
 * @主要功能：数据格式转换
 */
public class DataConvertUtils {
    public static int DOUBLELENGTH = 7;

    /**
     * int到byte[] 由高位到低位
     *
     * @param i 需要转换为byte数组的整行值。
     * @return byte数组
     */
    public static byte[] intToByteArray(int i) {
        byte[] result = new byte[4];
        result[0] = (byte) ((i >> 24) & 0xFF);
        result[1] = (byte) ((i >> 16) & 0xFF);
        result[2] = (byte) ((i >> 8) & 0xFF);
        result[3] = (byte) (i & 0xFF);

        return result;
    }

    /**
     * byte[]转int
     *
     * @param bytes 需要转换成int的数组
     * @return int值
     */
    public static int byteArrayToInt(byte[] bytes) {
        int value = 0;
        for (int i = 0; i < 4; i++) {
            int shift = (3 - i) * 8;
            value += (bytes[i] & 0xFF) << shift;
        }

        return value;
    }

    /**
     * 字节转十六进制
     *
     * @param b 需要进行转换的byte字节
     * @return 转换后的Hex字符串
     */
    public static String byteToHex(byte b) {
        String hex = Integer.toHexString(b & 0xFF);
        if (hex.length() < 2) {
            hex = "0" + hex;
        }

        return hex;
    }

    /**
     * 字节数组转16进制
     *
     * @param bytes 需要转换的byte数组
     * @return 转换后的Hex字符串
     */
    public static String bytesToHex(byte[] bytes) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < bytes.length; i++) {
            String hex = Integer.toHexString(bytes[i] & 0xFF);
            if (hex.length() < 2) {
                sb.append(0);
            }
            sb.append(hex);
        }

        return sb.toString();
    }

    /**
     * hex转byte数组
     *
     * @param hex
     * @return
     */
    public static byte[] hexToByte(String hex) {
        int m = 0, n = 0;
        int byteLen = hex.length() / 2; // 每两个字符描述一个字节
        byte[] ret = new byte[byteLen];
        for (int i = 0; i < byteLen; i++) {
            m = i * 2 + 1;
            n = m + 1;
            int intVal = Integer.decode("0x" + hex.substring(i * 2, m) + hex.substring(m, n));
            ret[i] = Byte.valueOf((byte) intVal);
        }

        return ret;
    }

    /**
     * byte数组转hex
     *
     * @param bytes
     * @return
     */
    public static String byteToHex(byte[] bytes) {
        String strHex = "";
        StringBuilder sb = new StringBuilder("");
        for (int n = 0; n < bytes.length; n++) {
            strHex = Integer.toHexString(bytes[n] & 0xFF);
            sb.append((strHex.length() == 1) ? "0" + strHex : strHex); // 每个字节由两个字符表示，位数不够，高位补0
        }

        return sb.toString().trim();
    }

    public static byte[] short2byte(short s) {
        byte[] b = new byte[2];
        for (int i = 0; i < 2; i++) {
            int offset = 16 - (i + 1) * 8; // 因为byte占4个字节，所以要计算偏移量
            b[i] = (byte) ((s >> offset) & 0xff); // 把16位分为2个8位进行分别存储
        }

        return b;
    }

    public static short byte2short(byte[] b) {
        return (short) ((b[0] & 0xff) | ((b[1] & 0xff) << 8));
    }

    public static long getUnsigned(int signed) {
        return signed >= 0 ? signed : 2 * (long) Integer.MAX_VALUE + 2 + signed;
    }

    /**
     * BigDecimal转换最简便,采用四舍五入方式
     *
     * @param num    要转换的数字
     * @param length 保留几位小数
     */
    public static double formatByBigDecimal(double num, int length) {
        BigDecimal bg = new BigDecimal(num);
        double f1 = bg.setScale(length, BigDecimal.ROUND_HALF_UP).doubleValue();

        return f1;
    }

    public static int getReadByte(int length) {
        int result = 0xFFFF;

        return result >> (16 - length);
    }

    public static Date dateNumToDate(int hour, int minute, int second, int ms) {
        long milliSecond = (hour * 3600 + minute * 60 + second) * 1000 + ms;
        Date date = new Date();
        date.setTime(milliSecond);

        return date;
    }

    public static long dateNumToLong(int hour, int minute, int second, int ms) {
        long milliSecond = (hour * 3600 + minute * 60 + second) * 1000 + ms;

        return milliSecond;
    }

    public static double[] fromDoubleToDateNum(double time) {
        double[] dateNum = new double[4];
        dateNum[0] = Math.floor(time / 3600000);
        dateNum[1] = Math.floor((time - dateNum[0] * 3600000) / 60000);
        dateNum[2] = Math.floor((time - dateNum[0] * 3600000 - dateNum[1] * 60000) / 1000);
        dateNum[0] = Math.floor(time - dateNum[0] * 3600000 - dateNum[1] * 60000 - dateNum[2] * 1000);

        return dateNum;
    }

    /**
     * byte数组转short数组
     *
     * @param src
     * @return
     */
    public static short toShortArray(byte[] src) {
        short dest = (short) ((src[0] & 0xff) | ((src[1] & 0xff) << 8));

        return dest;
    }

    public static int getNums(int num) {
        if (num == 0) {
            return 0;
        }
        int result = (int) Math.pow(2, num + 1) - 1;

        return result;
    }

    public static String getDateString(PcmTime time) {
        StringBuilder sb = new StringBuilder();
        if (time.hour < 10) {
            sb.append("0");
        }
        sb.append(time.hour);
        sb.append(":");
        if (time.minute < 10) {
            sb.append("0");
        }
        sb.append(time.minute);
        sb.append(":");
        if (time.second < 10) {
            sb.append("0");
        }
        sb.append(time.second);
        sb.append(".");

        int mm = (int) Math.floor(time.ms * 1000);
        if (mm < 10) {
            sb.append("00000");
        } else if (mm < 100) {
            sb.append("0000");
        } else if (mm < 1000) {
            sb.append("000");
        } else if (mm < 10000) {
            sb.append("00");
        } else if (mm < 100000) {
            sb.append("0");
        }
        sb.append(mm);

        return sb.toString();
    }
}
